package db

import (
	"database/sql"
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"log"
	"sync"
)

// ConnectionPool 连接池结构
type ConnectionPool struct {
	mu       sync.Mutex
	conns    chan *sql.DB
	factory  func() (*sql.DB, error)
	maxConns int
}

// NewConnectionPool 创建一个新的连接池
func NewConnectionPool(factory func() (*sql.DB, error), maxConns int) (*ConnectionPool, error) {
	conns := make(chan *sql.DB, maxConns)
	for i := 0; i < maxConns; i++ {
		conn, err := factory()
		if err != nil {
			return nil, err
		}
		conns <- conn
	}
	return &ConnectionPool{
		conns:    conns,
		factory:  factory,
		maxConns: maxConns,
	}, nil
}

// Get 获取一个连接
func (p *ConnectionPool) Get() (*sql.DB, error) {
	p.mu.Lock()
	defer p.mu.Unlock()

	select {
	case conn := <-p.conns:
		return conn, nil
	default:
		return p.factory()
	}
}

// Release 释放一个连接
func (p *ConnectionPool) Release(conn *sql.DB) {
	p.mu.Lock()
	defer p.mu.Unlock()

	select {
	case p.conns <- conn:
	default:
		conn.Close()
	}
}

func main() {
	// 数据库连接工厂函数
	factory := func() (*sql.DB, error) {
		user := "g_g_01film"
		pass := "TtnWAzw35kHMPxhT"
		dbname := "g_g_01film"
		mysqlUrl := user + ":" + pass + "@tcp(127.0.0.1:3306)/" + dbname
		return sql.Open("mysql", mysqlUrl)
	}

	// 创建连接池
	pool, err := NewConnectionPool(factory, 5)
	if err != nil {
		log.Fatalf("Error creating connection pool: %v", err)
	}

	// 获取连接
	conn, err := pool.Get()
	if err != nil {
		log.Fatalf("Error getting connection: %v", err)
	}

	// 使用连接
	rows, err := conn.Query("SELECT id, name FROM user")
	if err != nil {
		log.Fatalf("Error querying database: %v", err)
	}
	defer rows.Close()

	for rows.Next() {
		var id int
		var name string
		if err := rows.Scan(&id, &name); err != nil {
			log.Fatalf("Error scanning row: %v", err)
		}
		fmt.Printf("User: %d, %s\n", id, name)
	}

	// 释放连接
	pool.Release(conn)
}
